package com.fingard.dsp.bank.directbank.ceb01;

import java.io.File;
import java.sql.Connection;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import com.alibaba.fastjson.JSON;
import com.fingard.FGBiz;
import com.fingard.constant.Format;
import com.fingard.dsp.bank.directbank.DirectBase;
import com.fingard.io.FileHelper;
import com.fingard.net.FormSubmit;
import com.fingard.text.StringHelper;
import com.fingard.threading.ThreadPoolUtil;
import com.fingard.util.SmbFileUtil;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;

/**
 * @author Marlon
 * @date 2018/9/27
 */
public class CEB01SyncTask extends CEB01Base {

    private String actNum = "";
    private String dateFrom = "";
    private String dateTo = "";

    public CEB01SyncTask(String p_actNum, String p_dateFrom, String p_dateTo) {
        actNum = p_actNum;
        dateFrom = p_dateFrom;
        dateTo = p_dateTo;
    }

    public void downloadReceipt() {
        ThreadPoolUtil.execute(new Runnable() {
            @Override
            public void run() {
                String uploadType=SmbFileUtil.getUploadType();
                StringBuilder logSb = new StringBuilder();
                Connection conn = null;
                try {
                    setSbLog(logSb);
                    conn = FGBiz.getLocalDbConn();
                    WriteBankLogLn2(String.format("针对账号：[%s]，起始日期：[%s]，结束日期:[%s]的回单下载任务已开始执行", actNum, dateFrom, dateTo));
                    List<Map<String, String>> tmpResult = new ArrayList<Map<String, String>>();

                    Calendar tmpCalendarFrom = Calendar.getInstance();
                    tmpCalendarFrom.setTime(Format.Date8Format.parse(dateFrom));
                    Calendar tmpCalendarTo = Calendar.getInstance();
                    tmpCalendarTo.setTime(Format.Date8Format.parse(dateTo));
                    int tmpIntFrom = Integer.parseInt(Format.Date8Format.format(tmpCalendarFrom.getTime()));
                    int tmpIntTo = Integer.parseInt(Format.Date8Format.format(tmpCalendarTo.getTime()));
                    String strCurrency = getBankConfig().getMapValueByKey("elereceiptAccountInfo",actNum);
                    if (StringHelper.isNullOrEmpty(strCurrency)){
                        strCurrency = "1";
                    }
                    while (tmpIntFrom <= tmpIntTo) {
                        Date fromDateStep = tmpCalendarFrom.getTime();
                        int tmpAllNum = -1;//总条数
                        int tmpReadedNum = 0;//已读取数
                        int tmpEachReqLen = 50;//每次请求条数
                        int tmpStartNO = 0;//请求页码
                        String tmpRespCode = "";
                        String tmpRespInfo = "";
                        while (tmpRespCode.length() == 0) {//分页查询
                            tmpStartNO++;
                            XmlTextWriter xmlWriter = new XmlTextWriter();//发银行报文的XML对象
                            //写入通用的头部节点
                            CEB01Header bankHeader = new CEB01Header();
                            bankHeader.TransCode = "b2e005023";
                            bankHeader.batchID = getBatchID();
                            bankHeader.JnlDateTime = new Date();
                            writeCommonHeader_2(xmlWriter, bankHeader);
                            xmlWriter.writeStartElement("TransContent");
                            xmlWriter.writeStartElement("ReqData");
                            xmlWriter.writeElementString("ClientPatchID", bankHeader.batchID);
                            xmlWriter.writeElementString("OperationType", "0");
                            xmlWriter.writeElementString("ActNo", actNum);
                            xmlWriter.writeElementString("BillNumber", "");
                            xmlWriter.writeElementString("BeginDate", Format.Date8Format.format(fromDateStep));
                            xmlWriter.writeElementString("EndDate", Format.Date8Format.format(fromDateStep));
                            xmlWriter.writeElementString("BeginAmount", "");
                            xmlWriter.writeElementString("EndAmount", "");
                            xmlWriter.writeElementString("BeginNum", String.valueOf(tmpStartNO));
                            xmlWriter.writeElementString("QueryNum", String.valueOf(tmpEachReqLen));
                            xmlWriter.writeEndDocument();
                            //查询回单信息
                            String[] tmpStrRet = sendToBank_2(xmlWriter.toXmlString(), bankHeader.TransCode);
                            if (tmpStartNO > 1) {
                                tmpStrRet = new String[]{"", ""};
                            }
                            XmlTextReader tmpBkReader;
                            int tmpPageRdNum = 0;
                            if (tmpStrRet[0].length() == 0) {
                                StringBuilder tmpSbMsg = new StringBuilder();
                                tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                                if (tmpBkReader != null) {
                                    String tmpRetCode = tmpBkReader.getFirstText("/Transaction/TransContent/ReturnCode");
                                    String tmpRetMessage = tmpBkReader.getFirstText("/Transaction/TransContent/ReturnMsg");
                                    if ("0000".equals(tmpRetCode)) {
                                        //总记录数
                                        if (tmpAllNum == -1) {
                                            tmpAllNum = Integer.parseInt(tmpBkReader.getFirstText("/Transaction/TransContent/TotalNum"));
                                        }
                                        if (tmpAllNum <= 0) {
                                            tmpRespCode = "-1";
                                            tmpRespInfo = "查无回单";
                                            break;
                                        }
                                        while (tmpBkReader.read("/Transaction/TransContent/BatchRespList/RespData")) {
                                            tmpPageRdNum++;
                                            tmpReadedNum++;
                                            Map<String, String> tmpMap = new HashMap<String, String>();

                                            tmpMap.put("BillNumber", tmpBkReader.readedXElement.getSingleTextNotNull("BillNumber"));//回单编号
                                            tmpMap.put("WriteDate", tmpBkReader.readedXElement.getSingleTextNotNull("WriteDate"));//交易日期
                                            String AcNo = tmpBkReader.readedXElement.getSingleTextNotNull("AcNo");
                                            if (actNum.equals(AcNo)) {
                                                tmpMap.put("moneyway", "1");
                                                tmpMap.put("actNum", AcNo);//账号
                                                tmpMap.put("actName", tmpBkReader.readedXElement.getSingleTextNotNull("AcName"));//客户名称
                                                tmpMap.put("actBankName", tmpBkReader.readedXElement.getSingleTextNotNull("AcBankName"));//开户行
                                                tmpMap.put("oppActNum", tmpBkReader.readedXElement.getSingleTextNotNull("AcNo2"));//账号
                                                tmpMap.put("oppActName", tmpBkReader.readedXElement.getSingleTextNotNull("AcName2"));//客户名称
                                                tmpMap.put("oppActBankName", tmpBkReader.readedXElement.getSingleTextNotNull("AcBankName2"));//开户行
                                            } else {
                                                tmpMap.put("moneyway", "2");
                                                tmpMap.put("oppActNum", AcNo);//账号
                                                tmpMap.put("oppActName", tmpBkReader.readedXElement.getSingleTextNotNull("AcName"));//客户名称
                                                tmpMap.put("oppActBankName", tmpBkReader.readedXElement.getSingleTextNotNull("AcBankName"));//开户行
                                                tmpMap.put("actNum", tmpBkReader.readedXElement.getSingleTextNotNull("AcNo2"));//账号
                                                tmpMap.put("actName", tmpBkReader.readedXElement.getSingleTextNotNull("AcName2"));//客户名称
                                                tmpMap.put("actBankName", tmpBkReader.readedXElement.getSingleTextNotNull("AcBankName2"));//开户行
                                            }
                                            tmpMap.put("Amount", tmpBkReader.readedXElement.getSingleTextNotNull("Amount"));//交易金额
                                            tmpMap.put("FlowNumber", tmpBkReader.readedXElement.getSingleTextNotNull("FlowNumber"));//流水号
                                            tmpMap.put("ValidateCode", tmpBkReader.readedXElement.getSingleTextNotNull("ValidateCode"));//验证码
                                            tmpMap.put("BillQueryCode", tmpBkReader.readedXElement.getSingleTextNotNull("BillQueryCode"));//电子回单查询码
                                            tmpMap.put("Currency", strCurrency);//币种
                                            tmpMap.put("ClientPatchID", tmpBkReader.readedXElement.getSingleTextNotNull("ClientPatchID"));//银企通子流水号,与上送不一样
                                            tmpResult.add(tmpMap);
                                        }
                                    } else {
                                        tmpRespCode = "-1";
                                        tmpRespInfo = tmpRetMessage;
                                        break;
                                    }
                                } else {
                                    tmpRespCode = "-1";
                                    tmpRespInfo = tmpSbMsg.toString();
                                    break;
                                }
                            } else {
                                tmpRespCode = "-1";
                                tmpRespInfo = tmpStrRet[1];
                                break;
                            }
                            if (tmpPageRdNum == 0 || tmpReadedNum >= tmpAllNum) {
                                break;
                            }
                        }//分页查询
                        tmpCalendarFrom.add(Calendar.DAY_OF_MONTH, 1);
                        tmpIntFrom = Integer.parseInt(Format.Date8Format.format(tmpCalendarFrom.getTime()));
                        WriteBankLogLn(tmpRespInfo + "\r\n");
                    }
                    List<Map<String, String>> tmpResultAts = new ArrayList<Map<String, String>>();
                    for (Map<String, String> eachRecord : tmpResult) {
                        XmlTextWriter xmlWriter = new XmlTextWriter();//发银行报文的XML对象
                        //写入通用的头部节点
                        CEB01Header bankHeader = new CEB01Header();
                        bankHeader.TransCode = "b2e005023";
                        bankHeader.batchID = getBatchID();
                        bankHeader.JnlDateTime = new Date();
                        writeCommonHeader_2(xmlWriter, bankHeader);
                        xmlWriter.writeStartElement("TransContent");
                        xmlWriter.writeStartElement("ReqData");
                        xmlWriter.writeElementString("ClientPatchID", bankHeader.batchID);
                        xmlWriter.writeElementString("OperationType", "1");
                        xmlWriter.writeElementString("ActNo", actNum);
                        xmlWriter.writeElementString("BillNumber", eachRecord.get("BillNumber"));
                        xmlWriter.writeElementString("BeginDate", "");
                        xmlWriter.writeElementString("EndDate", "");
                        xmlWriter.writeElementString("BeginAmount", "");
                        xmlWriter.writeElementString("EndAmount", "");
                        xmlWriter.writeElementString("BeginNum", "1");
                        xmlWriter.writeElementString("QueryNum", "50");
                        xmlWriter.writeEndDocument();
                        //生成回单
                        String sleepTime = getBankConfig().getValueAsString("waitSecsEachReqForReceipt");
                        if (sleepTime.length() > 0) {
                            Thread.sleep(Long.parseLong(sleepTime) * 1000);
                        } else {
                            Thread.sleep(5000L);
                        }
                        String[] tmpStrRet = sendToBank_2(xmlWriter.toXmlString(), bankHeader.TransCode);
                        XmlTextReader tmpBkReader;
                        if (tmpStrRet[0].length() == 0) {
                            StringBuilder tmpSbMsg = new StringBuilder();
                            tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                            if (tmpBkReader != null) {
                                while (tmpBkReader.read("/Transaction/TransContent/RespData")) {
                                    String fileName = tmpBkReader.readedXElement.getSingleTextNotNull("fileName");
                                    if (!StringHelper.isNullOrEmpty(fileName)) {
                                        eachRecord.put("downloadFlag", "success");
                                        eachRecord.put("fileName", tmpBkReader.readedXElement.getSingleTextNotNull("fileName"));//文件名称
                                        if (getBankConfig().getValueAsString("waitSecsEachReqForReceipt").length() > 0) {
                                            Thread.sleep(Long.parseLong(sleepTime) * 1000);
                                        } else {
                                            Thread.sleep(5000L);
                                        }
                                        //下载回单
                                        String[] tmpStrRetDownLoad = sendToBankDownloadFile("", bankHeader.TransCode, fileName);
                                        XmlTextReader tmpBkReaderDownLoad;
                                        if (tmpStrRet[0].length() == 0) {
                                            StringBuilder tmpSbMsgDownLoad = new StringBuilder();
                                            tmpBkReaderDownLoad = loadBankRespXmlReader(tmpStrRetDownLoad[1], tmpSbMsgDownLoad);
                                            if (tmpBkReaderDownLoad != null) {
                                                String success = tmpBkReaderDownLoad.getFirstText("/transaction/success");
                                                String error = tmpBkReaderDownLoad.getFirstText("/transaction/error");
                                                if (!StringHelper.isNullOrEmpty(success) && StringHelper.isNullOrEmpty(error)) {
                                                    tmpResultAts.add(eachRecord);
                                                } else {
                                                    WriteBankLogLn(eachRecord.get("BillNumber") + "回单文件下载失败：" + error + "\r\n");
                                                }
                                            }
                                        } else {
                                            WriteBankLogLn(eachRecord.get("BillNumber") + "回单文件下载失败：" + tmpStrRet[1] + "\r\n");
                                        }
                                    } else {
                                        WriteBankLogLn(eachRecord.get("BillNumber") + "回单文件生成失败：" + tmpStrRet[1] + "\r\n");
                                    }
                                }
                            } else {
                                WriteBankLogLn(eachRecord.get("BillNumber") + "回单文件生成失败：" + tmpSbMsg.toString() + "\r\n");
                                eachRecord.put("downloadFlag", tmpSbMsg.toString());
                            }
                        } else {
                            WriteBankLogLn(eachRecord.get("BillNumber") + "回单文件生成失败：" + tmpStrRet[1] + "\r\n");
                            eachRecord.put("downloadFlag", tmpStrRet[1]);
                        }
                    }
                    for (Map<String, String> eachRecord : tmpResult) {
                        WriteBankLogLn(String.format("回单编号：[%s]所对应的处理结果：[%s]", eachRecord.get("BillNumber"), eachRecord.get("downloadFlag")));
                    }
                    StringBuilder json = new StringBuilder();
                    if(getBankConfig().getValueAsBool("receiptPushHasTenantId")){
                        json.append("tenantId="+FGBiz.dspCenter.dspSet.tenant+"&transType=downloadreceipt&data={\"rows\":[");
                    }else{
                        json.append("transType=downloadreceipt&data={\"rows\":[");
                    }
                    int uploadSucc = 0;
                    String bankReceiptMainDir = StringHelper.trimEnd(bankFront.bankReceiptMainDir, "/") + File.separator + Format.Date10Format.format(new Date());
                    for (Map<String, String> eachRecord : tmpResultAts) {
                        File receiptFile = new File(bankReceiptMainDir + File.separator + eachRecord.get("fileName"));
                        String tmpByDate = Format.Date8Format.format(new Date());
                        tmpByDate = tmpByDate.substring(0, 6) + "/" + tmpByDate.substring(6, 8) + "/" + reqHeader.bankCode + "/" + actNum + "/";
                        //上传文件到共享目录下
                        int result = -1;
                        String AtsFilePath = "";
                        if (receiptFile.exists()) {
                            if("smb".equals(uploadType)) {
                                WriteBankLogLn("正在上传文件至共享目录:" + FGBiz.dspCenter.dspSet.receiptShareDir);
                                result = SmbFileUtil.smbUploading(receiptFile.getPath(), tmpByDate, FGBiz.dspCenter.dspSet.receiptShareDir);
                                AtsFilePath = tmpByDate + receiptFile.getName();
                            } else if("localhost".equals(uploadType)){
                                String shareDir = StringHelper.trimEndFileSp(FGBiz.dspCenter.dspSet.receiptShareDir.split("@")[1]) + File.separator;
                                WriteBankLogLn("正在上传文件至本地共享目录:" + shareDir);
                                result = FileHelper.copyFile(receiptFile.getPath(), shareDir + tmpByDate + receiptFile.getName());
                                AtsFilePath = tmpByDate + receiptFile.getName();
                            } else {
                                tmpByDate =tmpByDate.replaceAll(reqHeader.bankCode + "/","");
                                WriteBankLogLn("正在上传文件至微服务:" + FGBiz.dspCenter.dspSet.receiptShareDir);
                                Map<String,String> map = FormSubmit.fileUpload
                                        (FGBiz.dspCenter.dspSet.receiptShareDir,actNum,receiptFile.getPath(),tmpByDate,receiptFile.getName(),getCharset());
                                WriteBankLogStep3(JSON.toJSONString(map));
                                if(map.keySet().size()!=0){
                                    result = Integer.valueOf(map.get("respCode"));
                                    tmpByDate =map.get("remotePath");
                                    AtsFilePath = tmpByDate;
                                }else{
                                    result = -1;
                                }
                            }
                        }
                        if (result == 0 || result == 1) {
                            uploadSucc++;
                            if (result == 0) {
                                WriteBankLogLn("文件上传成功");
                            } else {
                                WriteBankLogLn("文件已存在共享目录无需重复上传");
                            }
                            //推送数据给ATS处理
                            json.append("{");
                            json.append("\"actNum\":\"" + actNum + "\",");
                            json.append("\"actCur\":\"" + eachRecord.get("Currency") + "\",");
                            json.append("\"receiptCode\":\"" + eachRecord.get("BillNumber") + "\",");//回单编号
                            json.append("\"receiptType\":\"" + "" + "\",");//回单类型  1：存款回单；2：取款回单；3：转账回单；4：缴税回单；5：收费回单；6定期回单；7：活期回单
                            json.append("\"receiptState\":\"" + "" + "\",");//回单状态 1：正常；2：冲正；3：被冲正；4：当日冲正
                            json.append("\"oppActName\":\"" + eachRecord.get("oppActName") + "\",");
                            json.append("\"oppActNum\":\"" + eachRecord.get("oppActNum") + "\",");
                            json.append("\"amount\":\"" + eachRecord.get("Amount") + "\",");
                            json.append("\"moneyway\":\"" + eachRecord.get("moneyway") + "\",");
                            json.append("\"tranSeqNo\":\"" + eachRecord.get("FlowNumber") + "\",");
                            json.append("\"tranCode\":\"" + eachRecord.get("BillQueryCode") + "\",");//交易码?
                            json.append("\"tranDate\":\"" + Format.Date10Format.format(Format.Date8Format.parse(eachRecord.get("WriteDate"))) + "\",");
                            json.append("\"filePath\":\"" + AtsFilePath + "\",");//回单文件仓库存储路径
                            json.append("\"fileType\":\"1\"");
                            json.append("},");
                        } else {
                            WriteBankLogLn("上传文件至共享目录失败，请检查共享目录配置是否正确" + receiptFile.getPath());
                        }

                    }
                    if (uploadSucc > 0) {
                        json.deleteCharAt(json.length() - 1);
                        json.append("]}");
                        String[] data ;
                        String receiptPushType = FGBiz.dspCenter.dspSet.receiptPushType;
                        if("nbGateway".equals(receiptPushType)) {
                            WriteBankLogLn("3.推送给网关的数据" + json.toString());
                            DirectBase tmplogMsg = new DirectBase();
                            data= FormSubmit.receiptInfoSend(json.toString(),tmplogMsg,false);
                            WriteBankLogLn(tmplogMsg.getSbLog());
                            if (data[0].length() == 0 && data[1].equals("ok")) {
                                WriteBankLogLn("推送数据到网关成功,请查看数据");
                            } else {
                                WriteBankLogLn("推送数据到网关失败");
                            }
                        }else{
                            WriteBankLogLn("3.推送给ATS的数据" + json.toString());
                            data = sendToATS(json.toString());
                            if (data[0].length() == 0 && data[1].equals("ok")) {
                                WriteBankLogLn("推送数据到ATS成功,请查看数据");
                            } else {
                                WriteBankLogLn("推送数据到ATS失败");
                            }
                        }

                    } else {
                        WriteBankLogLn("成功保存文件条数为0，不需要推送数据到ATS");
                    }

                    WriteBankLogLn(String.format("总计：[%s]回单，下载成功：[%s]，上传成功:[%s]的回单下载任务已完成执行", tmpResult.size(), tmpResultAts.size(), uploadSucc));
                    WriteBankLogLn(String.format("针对账号：[%s]，起始日期：[%s]，结束日期:[%s]的回单下载任务已完成执行", actNum, dateFrom, dateTo));

                } catch (Exception ex) {
                    WriteBankLogLn(ex);
                    ex.printStackTrace();
                } finally {
                    String tmpDateDir = Format.DateForLogFormat.format(new Date()).replace("-", File.separator);
                    String tmpSubFileName = FGBiz.dspCenter.bankLogsFirstDir + File.separator + tmpDateDir + File.separator + "CEB01" + File.separator + "SyncTask-downloadReceipt" + "_" + actNum + "_" + Format.DateTime14Format.format(new Date()) + "_" + UUID.randomUUID() + ".txt";
                    String tmpLogFile = FGBiz.dspCenter.bankLogsDirPath + File.separator + tmpSubFileName;
                    try {
                        FileHelper.writeFile(tmpLogFile, logSb);
                    } catch (Exception ex) {
                        ex.printStackTrace();
                    }

                    if (conn != null) {
                        try {
                            conn.close();
                        } catch (Exception ex) {
                            ex.printStackTrace();
                        }
                    }
                }
            }
        });
    }

}
